import type {
  CommentInfo,
  QuoteNavigationUserInfo,
  UserCommentInfo,
  UserCommentNavigation,
  UserCommentSequence,
} from '../types'
import { ToolKit } from '../../../../../lib/utils/toolkit'
import { logger } from '../../../../../types/constants'
import { SYMBOLS } from '../../../../../types/interfaces'

export class ConversationFlowUser {
  readonly name: string = 'ConversationFlowUser'
  private static instance: ConversationFlowUser
  // 存储用户评论序列关系
  private userSequences: Map<string, UserCommentSequence> = new Map()
  // 用户评论索引映射
  private commentToUserMap: Map<string, string> = new Map()
  // 用户名到用户 ID 的映射
  private userNameToIdMap: Map<string, string> = new Map()
  /**
   * 获取单例实例
   */
  public static getInstance(): ConversationFlowUser {
    if (!ConversationFlowUser.instance) {
      ConversationFlowUser.instance = new ConversationFlowUser()
    }
    return ConversationFlowUser.instance
  }

  /**
   * 添加评论到用户序列中
   */
  addCommentToUserSequence(commentInfo: CommentInfo): void {
    const { id, floorNumber, timestamp, element, user } = commentInfo

    const userCommentInfo: UserCommentInfo = {
      id,
      floorNumber,
      timestamp,
      element,
    }

    // 确保用户 ID 存在
    const userId = this.ensureUserId(user)

    if (!this.userSequences.has(userId)) {
      // 新用户，创建序列
      this.userSequences.set(userId, {
        userId,
        username: user.name,
        comments: [userCommentInfo],
        commentCount: 1,
        firstCommentTime: timestamp,
        lastCommentTime: timestamp,
        commentIds: [id],
      })
    }
    else {
      // 现有用户，添加评论并重新排序
      const userSequence = this.userSequences.get(userId)!
      userSequence.comments.push(userCommentInfo)
      userSequence.commentIds.push(id)

      // 按时间重新排序
      this.sortUserCommentsByTime(userSequence)

      // 更新统计信息
      userSequence.commentCount = userSequence.comments.length
      userSequence.firstCommentTime = userSequence.comments[0].timestamp
      userSequence.lastCommentTime = userSequence.comments[userSequence.comments.length - 1].timestamp
    }

    // 建立评论到用户的映射
    this.commentToUserMap.set(id, userId)

    logger.debug(`[${this.name}] 添加评论到用户序列`, {
      userId,
      username: user.name,
      commentId: id,
      floorNumber,
      userCommentCount: this.userSequences.get(userId)?.commentCount,
    })
  }

  /**
   * 按时间对用户评论进行排序
   */
  private sortUserCommentsByTime(userSequence: UserCommentSequence): void {
    userSequence.comments.sort((a, b) =>
      new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime(),
    )
    userSequence.commentIds = userSequence.comments.map(comment => comment.id)
  }

  /**
   * 确保用户 ID 存在，如果不存在则生成
   */
  private ensureUserId(user: QuoteNavigationUserInfo): string {
    const { name, id } = user

    if (this.userNameToIdMap.has(name)) {
      return this.userNameToIdMap.get(name)!
    }

    // 生成基于用户名的唯一 ID
    const userId = id || ToolKit.string.generateTextHash(name)
    this.userNameToIdMap.set(name, userId)

    return userId
  }

  /**
   * 构建所有用户的评论导航关系
   */
  buildAllUserCommentNavigations(): void {
    this.userSequences.forEach((userSequence, userId) => {
      if (userSequence.commentCount <= 1) {
        return // 只有一个评论的用户不需要导航
      }

      userSequence.comments.forEach((comment, index) => {
        const navigation = this.buildCommentNavigation(userSequence, index)

        logger.debug(`[${this.name}] 构建用户评论导航`, {
          userId,
          username: userSequence.username,
          commentId: comment.id,
          navigation,
        })
      })
    })

    logger.important(`[${this.name}] ${SYMBOLS.STATUS.SUCCESS} 构建用户评论导航关系`, {
      totalUsers: this.userSequences.size,
      totalComments: this.commentToUserMap.size,
      multiCommentUsers: Array.from(this.userSequences.values()).filter(seq => seq.commentCount > 1).length,
    })
  }

  /**
   * 为单个评论构建导航信息
   */
  private buildCommentNavigation(userSequence: UserCommentSequence, commentIndex: number): UserCommentNavigation {
    const userCommentIndex = commentIndex + 1
    const userCommentCount = userSequence.commentCount

    return {
      previousCommentId: commentIndex > 0 ? userSequence.comments[commentIndex - 1].id : undefined,
      nextCommentId: commentIndex < userCommentCount - 1 ? userSequence.comments[commentIndex + 1].id : undefined,
      userCommentIndex,
      userCommentCount,
      isFirstUserComment: commentIndex === 0,
      isLastUserComment: commentIndex === userCommentCount - 1,
      userSequencePosition: `${userCommentIndex}/${userCommentCount}`,
    }
  }

  /**
   * 获取评论的用户导航信息
   */
  getCommentUserNavigation(commentId: string): UserCommentNavigation | null {
    const userId = this.commentToUserMap.get(commentId)
    if (!userId) {
      return null
    }

    const userSequence = this.userSequences.get(userId)
    if (!userSequence) {
      return null
    }

    const commentIndex = userSequence.comments.findIndex(comment => comment.id === commentId)
    if (commentIndex === -1) {
      return null
    }

    return this.buildCommentNavigation(userSequence, commentIndex)
  }

  /**
   * 获取用户的所有评论
   */
  getUserComments(userId: string): UserCommentInfo[] {
    const userSequence = this.userSequences.get(userId)
    return userSequence ? userSequence.comments : []
  }

  /**
   * 通过评论 ID 获取用户信息
   */
  getUserByCommentId(commentId: string): UserCommentSequence | null {
    const userId = this.commentToUserMap.get(commentId)
    return userId ? this.userSequences.get(userId) || null : null
  }

  /**
   * 获取所有用户序列
   */
  getAllUserSequences(): UserCommentSequence[] {
    return Array.from(this.userSequences.values())
  }

  /**
   * 获取多评论用户（评论数 > 1）
   */
  getMultiCommentUsers(): UserCommentSequence[] {
    return Array.from(this.userSequences.values()).filter(seq => seq.commentCount > 1)
  }

  /**
   * 获取用户统计信息
   */
  getUserStatistics(): {
    totalUsers: number
    totalComments: number
    multiCommentUsers: number
    singleCommentUsers: number
    averageCommentsPerUser: number
  } {
    const totalUsers = this.userSequences.size
    const totalComments = this.commentToUserMap.size
    const multiCommentUsers = this.getMultiCommentUsers().length
    const singleCommentUsers = totalUsers - multiCommentUsers
    const averageCommentsPerUser = totalUsers > 0 ? totalComments / totalUsers : 0

    return {
      totalUsers,
      totalComments,
      multiCommentUsers,
      singleCommentUsers,
      averageCommentsPerUser: Number(averageCommentsPerUser.toFixed(2)),
    }
  }

  /**
   * 清空所有数据
   */
  clear(): void {
    this.userSequences.clear()
    this.commentToUserMap.clear()
    this.userNameToIdMap.clear()
  }
}
